/*
 * redirect.c
 *
 *  Created on: 2024-01-01
 *      Author: liaofd
 */
#include "redirect_stdio_opt.h"
#include "log.h"
#include "cmsis_os.h"

#ifdef STDIO_USE_UART
# define xUSE_UART_BSP
# ifndef USE_UART_BSP
UART_HandleTypeDef *printf_huart = &huart1;
# else
#define PRINTF_UART_OBJ UART1_OBJ
# endif
#endif

#ifdef STDIO_ETH_W5500_SOCKET
app_socket_t *printf_socket = NULL;
#endif

#ifdef STDIO_ETH_SOCKET
extern int shell_client_fd;
#endif

static SemaphoreHandle_t mutex = NULL;

/**************************************************************************************/
/* Private function prototypes -----------------------------------------------*/
#ifdef __GNUC__
/* With GCC, small printf (option LD Linker->Libraries->Small printf
 set to 'Yes') calls __io_putchar() */
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */

/**
 * @brief  Retargets the C library printf function to the USART.
 * @param  None
 * @retval None
 */
#if 0
PUTCHAR_PROTOTYPE
{
	/* Place your implementation of fputc here */
	/* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */
#if 0
	uint8_t get_fw_upgrade_flag(void);
	if (get_fw_upgrade_flag()) //固件升级时不打印信息
		return ch;
#endif
#ifdef STDIO_USE_UART
	if(printf_huart != NULL && printf_huart->gState != HAL_UART_STATE_BUSY_TX)
	HAL_UART_Transmit(printf_huart, (uint8_t *)&ch, 1, 0xFFFF);
#endif

#ifdef STDIO_ETH_W5500_SOCKET
	if (printf_socket != NULL)
	{
		app_socket_send(printf_socket, (uint8_t *) &ch, 1);
	}
	else
	{
		printf_socket = app_socket_alloc(Sn_MR_TCP, TCP_UDP_SERVER, 10000, NULL,
				0);
	}
#endif

#if 0//def STDIO_ETH_SOCKET
	int fd = shell_client_fd;
	if(fd >= 0)
	{
		int ret = write(fd, (uint8_t *)&ch, 1);
		if (ret <= 0)
		{
			close(fd);
			shell_client_fd = -1;
		}
	}
#endif
	return ch;
}
#endif

#if defined( STDIO_ETH_W5500_SOCKET ) || defined( STDIO_ETH_SOCKET) || defined(STDIO_USE_UART)
int _write(int file, char *ptr, int len)
{
	if (mutex == NULL)
	    mutex = xSemaphoreCreateMutex();
	uint8_t get_fw_upgrade_flag(void);
	//if (is_app_direct_call_printf_disable()) //固件升级时不打印信息
	//	return len;

	uint8_t *pbuf = pvPortMalloc(len);
	if(pbuf == NULL)
		return -1;
	if (mutex)
		xSemaphoreTake(mutex, 5000);

	memcpy(pbuf, ptr, len);

#ifdef STDIO_USE_UART
# ifndef USE_UART_BSP
	if(printf_huart != NULL && printf_huart->gState != HAL_UART_STATE_BUSY_TX)
		HAL_UART_Transmit(printf_huart, (uint8_t *)pbuf, len, 0xFFFF);
# else
	uart_obj_write(PRINTF_UART_OBJ, (uint8_t *)pbuf, len);
# endif
#endif

#ifdef STDIO_ETH_W5500_SOCKET
	if (printf_socket != NULL)
	{
		app_socket_send(printf_socket, (uint8_t *) pbuf, (uint16_t) len);
	}
	/*else
	 {
	 printf_socket = app_socket_alloc(Sn_MR_TCP,TCP_UDP_SERVER,10000,NULL,0);
	 }*/
#endif
#ifdef STDIO_ETH_SOCKET
	if(shell_client_fd >= 0)
	{

		int fd = shell_client_fd;
#if 0
		fd_set write_set;
		int ret;
		/* Clear the reference set of socket */
		FD_ZERO(&write_set);
		/* Add the server socket */
		FD_SET(fd, &write_set);
		struct timeval timeout = { 0, 300000 };
		if (select(fd + 1, NULL , &write_set, NULL, &timeout) && FD_ISSET(fd, &write_set))
		{
			ret = write(fd, (uint8_t * ) pbuf, len);
			if (ret <= 0)
			{
				close(fd);
				shell_client_fd = -1;
			}
		}
#else
		int ret = write(fd, (uint8_t * ) pbuf, len);
		if (ret <= 0)
		{
			close(fd);
			shell_client_fd = -1;
		}
#endif
	}
#endif
	vPortFree(pbuf);
	if(mutex)
		xSemaphoreGive(mutex);
	return len;
}
#endif

